home *** CD-ROM | disk | FTP | other *** search
-
- #import "WWButton.h"
- #import "WWButtonCell.h"
- #import "WWTCLInterp.h"
-
- #import "avoidStupidWarnings.h"
-
- @implementation WWButtonCell
-
-
- + initialize { [WWButtonCell setVersion:3]; return self; }
- ////////////////////////////////////////////////////////
- //
- - init
- {
- [super init];
- controlStringSize = 32;
- controlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- tclExpressionSize = 32;
- tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
- tclVarSize = 32;
- tclVar = (char *)NXZoneCalloc([self zone], tclVarSize, sizeof(char));
- tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- interp = nil;
- tclCommandDirty = YES;
-
- return self;
- }
- //
- - awake
- {
- [super awake];
- tclCommandDirty = YES;
- return self;
- }
-
- - free
- {
- if (controlString) { NXZoneFree([self zone], controlString); }
- if (sprintfControlString) { NXZoneFree([self zone], sprintfControlString); }
- if (tclExpression) { NXZoneFree([self zone], tclExpression); }
- if (tclVar) { NXZoneFree([self zone], tclVar); }
- if (tclCommand) { NXZoneFree([self zone], tclCommand); }
- return [super free];
- }
-
- - reinitializeControlStringAndTclVarFromZone:(NXZone *)zone
- {
- controlString = (char *)NXZoneCalloc(zone, controlStringSize, sizeof(char));
- sprintfControlString = (char *)NXZoneCalloc(zone, controlStringSize, sizeof(char));
- tclExpression = (char *)NXZoneCalloc(zone, tclExpressionSize, sizeof(char));
- tclVar = (char *)NXZoneCalloc(zone, tclVarSize, sizeof(char));
- tclCommand = (char *)NXZoneCalloc(zone, tclCommandSize, sizeof(char));
- return self;
- }
-
- - copyFromZone:(NXZone *)zone
- {
- id newCopy = [super copyFromZone:zone];
-
-
- [newCopy reinitializeControlStringAndTclVarFromZone:zone];
- [newCopy setControlString:controlString];
- [newCopy setTclExpression:tclExpression];
- [newCopy setTclVar:tclVar];
- [newCopy setTclCommand:tclCommand];
-
- return newCopy;
- }
-
- - setInterp:newInterp { interp = newInterp; return self; }
- - interp { return interp; }
-
- - resizeTclCommandForArgVector:(char *)argOrderVector
- {
- BOOL done = NO;
-
-
- if (!done && !strcmp("d", argOrderVector))
- { while (tclCommandSize < (controlStringSize + 32))
- { if (!tclCommandSize)
- { tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- }
- else
- { tclCommandSize *= 2;
- tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
- }
- }
- done = YES;
- }
- if (!done && !strcmp("T", argOrderVector))
- { while (tclCommandSize < (controlStringSize + 32))
- { if (!tclCommandSize)
- { tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- }
- else
- { tclCommandSize *= 2;
- tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
- }
- }
- done = YES;
- }
- if (!done && !strcmp("f", argOrderVector))
- { while (tclCommandSize < (controlStringSize + 32) )
- { if (!tclCommandSize)
- { tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- }
- else
- { tclCommandSize *= 2;
- tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
- }
- }
- done = YES;
- }
-
- if (!done && !strcmp("s", argOrderVector))
- { const char *str = [self stringValue];
- int strLen = strlen(str);
-
- while (tclCommandSize < (controlStringSize + strLen))
- { if (!tclCommandSize)
- { tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- }
- else
- { tclCommandSize *= 2;
- tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
- }
- }
- done = YES;
- }
- // those were the easy ones; now for the permutations...
-
- return self;
- }
-
-
- - updateTclCommand
- {
- char *controlStringPtr, *sprintfControlStringPtr;
- BOOL done;
- int argOrderSize = 32;
- char *argOrderVector = (char *)NXZoneCalloc([self zone], argOrderSize, sizeof(char));
- int argOrderOffset = 0;
-
-
- if (!controlString)
- { return nil;
- }
-
- // we want to grovel over the controlString,
- // for right now, we really only tend to have the following patterns
- // in the controlString: 1 %f, 1 %d, 1 %s, %R, %G, %B, 1 %T
- controlStringPtr = controlString;
- sprintfControlStringPtr = sprintfControlString;
- strcpy(sprintfControlString, controlString);
- while (*controlStringPtr)
- { if (*controlStringPtr == '%')
- { sprintfControlStringPtr++; controlStringPtr++;
- if (*controlStringPtr)
- { switch (*controlStringPtr)
- { case 'd': while (argOrderOffset >= argOrderSize)
- { argOrderSize *= 2;
- argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
- }
- argOrderVector[argOrderOffset++] = 'd';
- sprintfControlStringPtr++; controlStringPtr++;
- break;
- case 'T': while (argOrderOffset >= argOrderSize)
- { argOrderSize *= 2;
- argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
- }
- argOrderVector[argOrderOffset++] = 'T';
- *sprintfControlStringPtr++ = 'd'; controlStringPtr++;
- break;
- case 'f': while (argOrderOffset >= argOrderSize)
- { argOrderSize *= 2;
- argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
- }
- argOrderVector[argOrderOffset++] = 'f';
- sprintfControlStringPtr++; controlStringPtr++;
- break;
- case 's': while (argOrderOffset >= argOrderSize)
- { argOrderSize *= 2;
- argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
- }
- argOrderVector[argOrderOffset++] = 's';
- sprintfControlStringPtr++; controlStringPtr++;
- break;
- case '%': sprintfControlStringPtr++; controlStringPtr++;
- break;
- default: NXLogError("WWSliderCell: unknown specifier <%c> in controlString.\n", *controlStringPtr);
- sprintfControlStringPtr++; controlStringPtr++;
- break;
- }
- }
- }
- else
- { sprintfControlStringPtr++; controlStringPtr++;
- }
- }
- argOrderVector[argOrderOffset] = 0;
-
- done = NO;
-
- if (!done && !strcmp("d", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self intValue]);
- done = YES;
- }
- if (!done && !strcmp("f", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self floatValue]);
- done = YES;
- }
- if (!done && !strcmp("s", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self stringValue]);
- done = YES;
- }
- if (!done && !strcmp("T", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self tag]);
- done = YES;
- }
- if (!done && !strcmp("dT", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self intValue], [self tag]);
- done = YES;
- }
- if (!done && !strcmp("fT", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self floatValue], [self tag]);
- done = YES;
- }
- if (!done && !strcmp("sT", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self stringValue], [self tag]);
- done = YES;
- }
- if (!done && !strcmp("Td", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self tag], [self intValue]);
- done = YES;
- }
- if (!done && !strcmp("Tf", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self tag], [self floatValue]);
- done = YES;
- }
- if (!done && !strcmp("Ts", argOrderVector))
- { [self resizeTclCommandForArgVector:argOrderVector];
- sprintf(tclCommand, sprintfControlString, [self tag], [self stringValue]);
- done = YES;
- }
-
- if (!done)
- { while (tclCommandSize < controlStringSize)
- { if (!tclCommandSize)
- { tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- }
- else
- { tclCommandSize *= 2;
- tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
- }
- }
- strcpy(tclCommand, controlString);
- }
- tclCommandDirty = NO;
-
- NXZoneFree([self zone], argOrderVector);
-
- return self;
- }
-
-
- - evaluateSelf
- {
- int ret;
- char *newStringValue;
- id retID;
-
-
- newStringValue = [interp globalEval:tclExpression :&ret];
- if ((ret == TCL_OK) || (ret == TCL_RETURN))
- { [self setStringValue:newStringValue];
- retID = self;
- }
- else
- { NXLogError("WWSliderCell: error <%s> evaluating tcl expression <%s>\n",
- newStringValue, tclExpression);
- if (newStringValue) { free(newStringValue); }
- retID = nil;
- }
- return retID;
- }
-
- - updateInterp
- {
- if ([interp eval:[self tclCommand]])
- { return self;
- }
- return nil;
- }
-
- - setIntValue:(int)val
- {
- [super setIntValue:val];
- tclCommandDirty = YES;
- return self;
- }
-
- - setFloatValue:(float)val
- {
- [super setFloatValue:val];
- tclCommandDirty = YES;
- return self;
- }
-
- - setDoubleValue:(double)val
- {
- [super setDoubleValue:val];
- tclCommandDirty = YES;
- return self;
- }
-
- - setStringValue:(const char *)str
- {
- [super setStringValue:str];
- if (str && *str)
- { [self setIntValue:atoi(str)];
- }
- else
- { [self setIntValue:0];
- }
- return self;
- }
-
-
- - setControlString:(const char *)str
- {
- int cnt;
-
-
- if (!str) { return self; }
- if (controlStringSize <= 0)
- { controlStringSize = 32;
- controlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- }
- cnt = strlen(str);
- while (cnt >= controlStringSize)
- { controlStringSize *= 2;
- controlString = (char *)NXZoneRealloc([self zone], controlString, controlStringSize);
- }
- if (sprintfControlString)
- { sprintfControlString = (char *)NXZoneRealloc([self zone], sprintfControlString, controlStringSize);
- }
- else
- { sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- }
- strcpy(controlString, str);
- tclCommandDirty = YES;
- return self;
- }
- //
- - (const char *)controlString { return controlString; }
-
- - setTclExpression:(const char *)str
- {
- int cnt;
-
-
- if (!str) { return self; }
- if (tclExpressionSize <= 0)
- { tclExpressionSize = 32;
- tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
- }
- cnt = strlen(str);
- while (cnt >= tclExpressionSize)
- { tclExpressionSize *= 2;
- tclExpression = (char *)NXZoneRealloc([self zone], tclExpression, tclExpressionSize);
- }
- strcpy(tclExpression, str);
- return self;
- }
- //
- - (const char *)tclExpression { return tclExpression; }
-
- - setTclVar:(const char *)str
- {
- int cnt;
-
-
- if (!str) { return self; }
- if (tclVarSize <= 0)
- { tclVarSize = 32;
- tclVar = (char *)NXZoneCalloc([self zone], tclVarSize, sizeof(char));
- }
- cnt = strlen(str);
- while (cnt >= tclVarSize)
- { tclVarSize *= 2;
- tclVar = (char *)NXZoneRealloc([self zone], tclVar, tclVarSize);
- }
- strcpy(tclVar, str);
- return self;
- }
- //
- - (const char *)tclVar { return tclVar; }
-
- - setTclCommand:(const char *)str
- {
- int cnt;
-
-
- if (!str) { return self; }
- if (tclCommandSize <= 0)
- { tclCommandSize = 32;
- tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
- }
- cnt = strlen(str);
- while (cnt >= tclCommandSize)
- { tclCommandSize *= 2;
- tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
- }
- strcpy(tclCommand, str);
- return self;
- }
- //
- - (const char *)tclCommand
- {
- if (tclCommandDirty)
- { [self updateTclCommand];
- }
- return tclCommand;
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteType(stream, "*", &controlString);
- NXWriteType(stream, "*", &tclVar);
- NXWriteType(stream, "*", &tclExpression);
- NXWriteType(stream, "*", &tclCommand);
- NXWriteObjectReference(stream, interp);
- return self;
- }
- //
- - read:(NXTypedStream *)stream
- {
- int version;
-
- [super read:stream];
-
- version = NXTypedStreamClassVersion(stream, "WWButtonCell");
- if (version == 1)
- { NXReadType(stream, "*", &controlString);
- if (controlString)
- { controlStringSize = strlen(controlString) + 1;
- sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- }
- else
- { controlStringSize = 0;
- sprintfControlString = NULL;
- }
- NXReadType(stream, "*", &tclVar);
- if (tclVar)
- { tclVarSize = strlen(tclVar) + 1;
- }
- else
- { tclVarSize = 0;
- }
- tclExpressionSize = 32;
- tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
- }
- if (version == 2)
- { NXReadType(stream, "*", &controlString);
- if (controlString)
- { controlStringSize = strlen(controlString) + 1;
- sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- }
- else
- { controlStringSize = 0;
- sprintfControlString = NULL;
- }
- NXReadType(stream, "*", &tclVar);
- if (tclVar)
- { tclVarSize = strlen(tclVar) + 1;
- }
- else
- { tclVarSize = 0;
- }
- NXReadType(stream, "*", &tclExpression);
- if (tclExpression)
- { tclExpressionSize = strlen(tclExpression) + 1;
- }
- else
- { tclExpressionSize = 0;
- }
- }
- if (version == 3)
- { NXReadType(stream, "*", &controlString);
- if (controlString)
- { controlStringSize = strlen(controlString) + 1;
- sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
- }
- else
- { controlStringSize = 0;
- sprintfControlString = NULL;
- }
- NXReadType(stream, "*", &tclVar);
- if (tclVar)
- { tclVarSize = strlen(tclVar) + 1;
- }
- else
- { tclVarSize = 0;
- }
- NXReadType(stream, "*", &tclExpression);
- if (tclExpression)
- { tclExpressionSize = strlen(tclExpression) + 1;
- }
- else
- { tclExpressionSize = 0;
- }
- NXReadType(stream, "*", &tclCommand);
- if (tclCommand)
- { tclCommandSize = strlen(tclCommand) + 1;
- }
- else
- { tclCommandSize = 0;
- }
- interp = NXReadObject(stream);
- }
- return self;
- }
-
- // IB stuff
- - (const char *)getInspectorClassName
- {
- NXEvent *event = [NXApp currentEvent];
-
- if (event->flags & NX_ALTERNATEMASK)
- { return [super getInspectorClassName];
- }
-
- return "WWButtonCellIBInspector";
- }
-
- @end
-